/*
** Haaf's Game Engine 1.7
** Copyright (C) 2003-2007, Relish Games
** hge.relishgames.com
**
** hgeStringTable helper class implementation
*/


#include "..\..\include\hgestrings.h"
//#include <ctype.h>

const HGE_CHAR STRHEADERTAG[]=TXT("[HGESTRINGTABLE]");
const HGE_CHAR STRFORMATERROR[]=TXT("String table %s has incorrect format.");


HGE *hgeStringTable::hge=0;


bool isspc(HGE_CHAR ch) {
	if(ch == TXT(' ') || ch == TXT('\t') || ch == TXT('\n') || ch == TXT('\r')) return true;
	return false;
}


hgeStringTable::hgeStringTable(const HGE_CHAR *filename)
{
	int i;
	void *data;
	DWORD size;
	HGE_CHAR *desc, *pdesc;
	NamedString *str;
	HGE_CHAR str_name[MAXSTRNAMELENGTH];
	HGE_CHAR *str_value, *pvalue;
	
	hge=hgeCreate(HGE_VERSION);
	strings=0;

	// load string table file
	data=hge->Resource_Load(filename, &size);
	if(!data) return;

#ifdef UNICODE
	desc = new wchar_t[size/2]; // -1+1, delete unicode signature
	memcpy(desc,(wchar_t*)data+1,size-2);
	desc[size/2-1]=0;
#else
	desc = new char[size+1];
	memcpy(desc,data,size);
	desc[size]=0;
#endif
	/*desc = new HGE_CHAR[size/sizeof(HGE_CHAR)+2-sizeof(HGE_CHAR)]; // -1+1, delete unicode signature
	memcpy(desc,(HGE_CHAR*)data+(sizeof(HGE_CHAR)-1),size-(sizeof(HGE_CHAR)*2-2));
	desc[size/sizeof(HGE_CHAR)-(sizeof(HGE_CHAR)-1)]=0;*/
	hge->Resource_Free(data);

	// check header
	if(memcmp(desc, STRHEADERTAG, sizeof(STRHEADERTAG)-sizeof(HGE_CHAR)))
	{
		hge->System_Log(STRFORMATERROR, filename);
		delete[] desc;	
		return;
	}

	pdesc=desc+sizeof(STRHEADERTAG)/sizeof(HGE_CHAR)+sizeof(HGE_CHAR)-1;
	str_value=new HGE_CHAR[8192];

	for(;;)
	{
		// skip whitespaces
		while(isspc(*pdesc)) pdesc++;
		if(!*pdesc) break;

		// skip comments
		if(*pdesc==';')
		{
			while(*pdesc && *pdesc != TXT('\n')) pdesc++;
			pdesc++;
			continue;
		}

		// get string name -> str_name
		i=0;
		while(pdesc[i] && pdesc[i]!=TXT('=') && !isspc(pdesc[i]) && i<MAXSTRNAMELENGTH)
		{
			str_name[i]=pdesc[i];
			i++;
		}
		str_name[i]=0;
		pdesc+=i;

		// skip string name overflow characters
		while(*pdesc && *pdesc!=TXT('=') && !isspc(*pdesc)) pdesc++;
		if(!*pdesc) break;

		// skip whitespaces to '='
		while(isspc(*pdesc)) pdesc++;
		if(*pdesc!=TXT('='))	{ hge->System_Log(STRFORMATERROR, filename); break; }
		pdesc++;

		// skip whitespaces to '"'
		while(isspc(*pdesc)) pdesc++;
		if(*pdesc!=TXT('"'))	{ hge->System_Log(STRFORMATERROR, filename); break;	}
		pdesc++;

		// parse string value till the closing '"' -> str_value
		// consider: \", \n, \\, LF, CR, whitespaces at line begin/end
		pvalue=str_value;

		while(*pdesc && *pdesc!=TXT('"'))
		{
			if(*pdesc==TXT('\n') || *pdesc==TXT('\r'))
			{
				while(isspc(*pdesc)) pdesc++;

				pvalue--;
				while(pvalue>=str_value && isspc(*pvalue)) pvalue--;
				pvalue++; *pvalue=TXT(' '); pvalue++;

				continue;
			}

			if(*pdesc==TXT('\\'))
			{
				pdesc++;
				if(!*pdesc) continue;
				if(*pdesc==TXT('n')) *pvalue=TXT('\n');
				else *pvalue=*pdesc;
				pvalue++;
				pdesc++;
				continue;
			}

			*pvalue=*pdesc; pvalue++;
			pdesc++;
		}

		*pvalue=0;

		// add the parsed string to the list
		str=new NamedString;
		HGE_SCPY(str->name, str_name);
		str->string=new HGE_CHAR[HGE_SLEN(str_value)+1];
		HGE_SCPY(str->string, str_value);
		str->next=strings;
		strings=str;

		//hge->System_Log(L"[%s] = '%s'", str->name, str->string);

		if(!*pdesc) break;
		pdesc++;
	}

	delete[] str_value;
	delete[] desc;
}

hgeStringTable::~hgeStringTable()
{
	NamedString *str, *strnext;

	str=strings;
	while(str)
	{
		strnext=str->next;
		delete[] str->string;
		delete str;
		str=strnext;
	}

	hge->Release();
}

HGE_CHAR *hgeStringTable::GetString(const HGE_CHAR *name)
{
	NamedString *str=strings;

	while(str)
	{
		if(!HGE_SCMP(name, str->name)) return str->string;
		str=str->next;
	}

	return 0;
}
